<!-- 素材上传页面 -->
<template>
	<view>
		<uv-form labelPosition="left" :model="model" :rules="rules" ref="form" labelWidth="70">
			<uv-form-item label="素材标题:" prop="material.materialTitle" borderBottom>
				<uv-input v-model="model.material.materialTitle" border="surround" clearable />
			</uv-form-item>
			<uv-form-item label="素材类型:" prop="material.typeName" borderBottom @click="showmaterialTypeSelect">
				<uv-input v-model="model.material.typeName" disabled disabledColor="#ffffff" placeholder="请选择素材类型"
					border="surround" />
				<template v-slot:right>
					<uv-icon name="arrow-right" />
				</template>
			</uv-form-item>
			<uv-form-item label="素材封面:" prop="material.thumbnailUrl">
				<uv-upload :fileList="model.thumbnailUrlList" name="thumbnailUrl" :maxCount="1" uploadIcon="plus"
					uploadText="一张图片" accept="image" @afterRead="uploadThumbnailUrl" @delete="deletePic"
					:previewFullImage="true" previewImage></uv-upload>
			</uv-form-item>
			<uv-form-item label="素材格式:" prop="material.materialFormatType" borderBottom>
				<uv-input placeholder="" border="surround" v-model="model.material.materialFormatType"></uv-input>
			</uv-form-item>
			<uv-form-item label="素材:" prop="material.materialUrl">
				<uv-upload :fileList="model.materialUrlList" name="materialUrl" :maxCount="3" uploadIcon="plus"
					uploadText="三张图片/一个视频或音频" accept @afterRead="uploadMaterialUrl" @delete="deleteMaterial"
					:previewFullImage="true" previewImage></uv-upload>
			</uv-form-item>
			<uv-form-item label="素材内容:" prop="material.materialSummary">
				<uv-textarea v-model="model.material.materialSummary" :maxlength="-1" autoHeight
					placeholder="请输入内容"></uv-textarea>
			</uv-form-item>
			<uv-form-item label="素材标签:" prop="material.materialTags">
				<view style="display: flex; gap:20px;">
					<uv-tags :text="item" v-for="(item, index) in model.material.materialTags" :key="index"
						:name="index" size="medium" closable @close="closeTag" style="margin-right: 20px;"></uv-tags>
				</view>
			</uv-form-item>
			<uv-form-item label="添加标签:">
				<uv-input placeholder="输入一个标签,确定/回车后就会添加" v-model="model.tagInfo" @confirm="addTag"
					clearable></uv-input>
			</uv-form-item>
			<uv-button type="primary" text="提交" customStyle="margin-top: 10px" @click="submit" />
			<uv-button type="error" text="重置" customStyle="margin-top: 10px" @click="reset" />
		</uv-form>
		<uv-action-sheet ref="materialTypeSelect" :actions="actions" title="请选择素材类型"
			@select="handleMaterialTypeSelect" />
	</view>
</template>

<script setup>
	import {
		ref,
		computed,
		reactive
	} from "vue"
	import {
		onLoad,
		onReady,
		onPageScroll,
		onShow,
		onReachBottom,
		onUnload
	} from "@dcloudio/uni-app"
	import {
		getMaterialTypeNameList
	}
	from "@/api/classify.js"
	import {
		uploadFile
	} from "@/utils/request.js"
	import {
		addMaterial,
		deleteOssFile
	} from "@/api/material.js"

	const model = reactive({
		material: {
			materialTags: [],
			materialUrl: [],
			fileSize: 0,

			// auditStatus: 2,
			// collectionCount: 5,
			// createBy: "hiyori",
			// createTime: "2025-03-08 23:37:58",
			// delFlag: 0,
			// fileSize: 156.8,
			// materialFormatType: "webp",
			// materialId: "7462571",
			// materialSummary: "雷姆(レム)是长月达平所创作的轻小说《Re:从零开始的异世界生活》及其衍生作品的登场角色。",
			// materialTags: ["雷姆", "Re:0"],
			// materialTitle: "雷姆",
			// materialType: "4960462",
			// materialUrl: [
			// 	"https://z-mytest.oss-cn-beijing.aliyuncs.com/creative/2eab3ae0-6850-4e8e-acb4-42a6662806c9.webp",
			// 	"https://z-mytest.oss-cn-beijing.aliyuncs.com/creative/55acc12c-32bd-4117-bd61-7e928be5f5c3.webp"
			// ],
			// publishTime: "2025-03-08 23:37:58",
			// remark: null,
			// showState: 0, // 改为使用showState字段
			// thumbnailUrl: "https://z-mytest.oss-cn-beijing.aliyuncs.com/creative/2eab3ae0-6850-4e8e-acb4-42a6662806c9.webp",
			// typeName: "动漫",
			// updateBy: "hiyuhi",
			// updateTime: "2025-04-12 22:04:22"
		},
		// 分类类型
		materialTypeList: [],
		// 缩略图
		thumbnailUrlList: [],
		// 上传素材列表
		materialUrlList: [],
		// 添加标签
		tagInfo: ""
	});
	const form = ref(null);
	// 素材类型选择
	const materialTypeSelect = ref(null);

	const actions = computed(() => {
		return model.materialTypeList.map((item) => {
			return {
				name: item.typeName,
				value: item.typeId,
			};
		});
	});

	const rules = reactive({
		'material.materialTitle': {
			type: 'string',
			required: true,
			message: '请填写标题',
			trigger: ['blur', 'change'],
		},
		'material.typeName': {
			type: 'string',
			max: 3,
			required: true,
			message: '请选择素材类型',
			trigger: ['blur', 'change'],
		},
		'material.thumbnailUrl': {
			type: 'string',
			required: false,
			message: '请上传封面',
			trigger: ['blur', 'change']
		},
		'material.materialUrl': {
			type: 'array',
			required: true,
			message: '请上传素材',
			trigger: ['blur', 'change']

		}
	});

	onReady(() => {
		// 获取素材类型
		getMaterialTypeList()
	})

	// 获取素材类型
	const getMaterialTypeList = async () => {
		const res = await getMaterialTypeNameList()
		if (res.code === 200) {
			model.materialTypeList = res.data
		}
	}

	// 上传封面
	const uploadThumbnailUrl = async (event) => {
		console.log("上传事件：", event);
		// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
		let lists = [].concat(event.file)
		let fileListLen = model.thumbnailUrlList.length
		lists.map((item) => {
			model.thumbnailUrlList.push({
				...item,
				status: 'uploading',
				message: '上传中'
			})
		})
		for (let i = 0; i < lists.length; i++) {
			const result = await uploadFilePromise(lists[i].url)
			console.log("res:", result.filePath);
			let item = model.thumbnailUrlList[fileListLen]
			// 将item对象与status、message、url属性合并，并插入到thumbnailUrlList数组的fileListLen位置
			model.thumbnailUrlList.splice(fileListLen, 1, Object.assign(item, {
				status: 'success',
				message: '',
				url: result.filePath
			}))
			// 给表单的thumbnailUrl字段赋值
			model.material.thumbnailUrl = result.filePath

			// fileListLen自增
			fileListLen++
		}
	};

	// 上传素材
	const uploadMaterialUrl = async (event) => {
		console.log("上传事件：", event);
		// 对上传的元素进行判断

		// 如果上传的是视频或音频，则只能上传一个文件
		if (event.file.type == "video" || event.file.type == "audio") {
			if (model.materialUrlList.length > 0) {
				uni.showToast({
					icon: 'error',
					title: '视频或音频只能上传一个',
				});
				return;
			}
		}

		// 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
		let lists = [].concat(event.file)
		let fileListLen = model.materialUrlList.length
		lists.map((item) => {
			model.materialUrlList.push({
				...item,
				status: 'uploading',
				message: '上传中'
			})
		})
		for (let i = 0; i < lists.length; i++) {
			const result = await uploadFilePromise(lists[i].url)
			let item = model.materialUrlList[fileListLen]
			// 将item对象与status、message、url属性合并，并插入到materialUrlList数组的fileListLen位置
			model.materialUrlList.splice(fileListLen, 1, Object.assign(item, {
				status: 'success',
				message: '',
				url: result.filePath
			}))
			// 给表单的materialUrl字段赋值
			model.material.materialUrl.push(result.filePath)
			// 计算上传文件大小
			// 计算总大小（单位：KB）
			const totalSize = model.materialUrlList.reduce((sum, item) => sum + item.size, 0);
			model.material.fileSize = totalSize.toFixed(2);
			// fileListLen自增
			fileListLen++
		}

		// 将文件列表的第一个文件的格式设置为素材格式
		if (model.materialUrlList.length > 0) {
			let suffix = model.materialUrlList[0].url.split('.').pop()
			model.material.materialFormatType = suffix
		}
	};

	// 删除封面
	const deletePic = (event) => {
		var deleteData = model.thumbnailUrlList.splice(event.index, 1);
		// 获取删除文件的信息
		console.log("删除的元素：", deleteData);
		// 获取文件名
		var fileName = deleteData[0].url.split("/").pop();
		// 获取素材的返回地址，并加入一个数组中
		var arr = [fileName]
		// 删除文件的oss地址 
		deleteOssFile(arr)
	};

	// 删除素材
	const deleteMaterial = (event) => {

		// 如果删除一个元素，则返回一个元素的数组。 如果未删除任何元素，则返回空数组。
		var deleteData = model.materialUrlList.splice(event.index, 1);
		// 获取删除文件的信息
		console.log("删除的元素：", deleteData);
		// 获取文件名
		var fileName = deleteData[0].url.split("/").pop();
		// 获取素材的返回地址，并加入一个数组中
		var arr = [fileName]
		// 删除文件的oss地址
		deleteOssFile(arr)

	};


	const submit = () => {
		form.value.validate().then((res) => {
			// 校验通过，提交表单数据
			// 设置表单数据  状态
			model.material.delFlag = 0;
			model.material.auditStatus = 1;
			model.material.showState = 1;
			// Json化数据 素材地址、素材tag	
			model.material.materialUrl = JSON.stringify(model.material.materialUrl);
			model.material.materialTags = JSON.stringify(model.material.materialTags);
			// 进行内容安全校验
			// 提交数据
			addMaterial(model.material).then(res => {
				if (res.code === 200) {
					uni.showToast({
						icon: 'success',
						title: '上传成功',
					});
					// 重置表单
					reset();
				} else {
					uni.showToast({
						icon: 'error',
						title: '上传失败',
					});
					// 清空标签
					model.material.materialTags = []
					model.tagInfo = "";
				}
			})
		}).catch(errors => {
			uni.showToast({
				icon: 'error',
				title: '校验失败',
			});
		});
	};

	const reset = () => {
		form.value.resetFields();
		form.value.clearValidate();
		// 清除上传的文件
		model.thumbnailUrlList = [];
		model.materialUrlList = [];
		model.tagInfo = "";
		model.material.materialTags = []
	};

	const showmaterialTypeSelect = () => {
		materialTypeSelect.value.open();
		uni.hideKeyboard();
	};

	const handleMaterialTypeSelect = (e) => {
		model.material.typeName = e.name;
		model.material.materialType = e.value;
		
	};
	// 上传文件的中间件函数
	const uploadFilePromise = (url) => {
		return new Promise((resolve, reject) => {
			uploadFile(url).then((res) => {
				console.log("返回信息：", res);
				resolve(res)
			}).catch((err) => {
				reject(err)
			})
		})
	}

	// 清除标签
	const closeTag = (name) => {
		console.log('点击标签', name);
		model.material.materialTags.splice(name, 1);
	}

	// 添加标签
	const addTag = () => {
		if (model.tagInfo) {
			model.material.materialTags.push(model.tagInfo);
			model.tagInfo = "";
		}
	};

	// 页面离开
	onUnload(() => {
		// console.log("离开页面了！");
		// 如果缩略图/素材列表不为空，则删除文件
		if (model.thumbnailUrlList.length > 0 || model.materialUrlList.length > 0) {
			// 获取缩略图/素材列表的文件名
			var thumbnailFileName = model.thumbnailUrlList.map(item => item.url.split("/").pop());
			var materialFileName = model.materialUrlList.map(item => item.url.split("/").pop());
			// 将文件名合并为一个数组
			var arr = thumbnailFileName.concat(materialFileName);
			// 删除文件的oss地址
			deleteOssFile(arr)
		}
	})
</script>

<style lang="scss" scoped>

</style>